2

@Scope

用于指定一个Bean的生命周期。

  • @Scope注解的作用相当于xml配置中的scope属性
<!--scope的默认是-->
<bean id="person" class="com.sff.app.bean.Person" scope="prototype"/>
  • ConfigurableBeanFactory.SCOPE_SINGLETON:表示单实例的对象,在spring容器启动的时候创建,以后每次获取时都从容器中取。
@Configuration
public class AppConfig2 {
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
    public Person person() {
        System.out.println("给spring ioc容器中添加bean");
        return new Person("Mate", 12);
    }
}

用单元测试获取bean

public void test02() {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);

        System.out.println("spring ioc容器启动完成");

        Person person = (Person) ctx.getBean("person");
        Person person1 = (Person) ctx.getBean("person");

        //==比较两个对象的地址值
        System.out.println(person == person1);
    }

运行结果:
给spring ioc容器中添加bean
spring ioc容器启动完成
true

我们获取了Person对象两次,但Person对象往容器中只添加了一下;

  • ConfigurableBeanFactory.SCOPE_PROTOTYPE:多实例的,容器启动的时候不会创建Bean,每次调用Bean的创建方法都会创建一个实例Bean。
@Configuration
public class AppConfig2 {
    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public Person person() {
        System.out.println("给spring ioc容器中添加bean");
        return new Person("Mate", 12);
    }
}

用单元测试获取bean

public void test02() {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);

        System.out.println("spring ioc容器启动完成");

        Person person = (Person) ctx.getBean("person");
        Person person1 = (Person) ctx.getBean("person");

        //==比较两个对象的地址值
        System.out.println(person == person1);
    }

运行结果:
spring ioc容器启动完成
给spring ioc容器中添加bean
给spring ioc容器中添加bean
false

@Lazy

懒加载,针对的是单实例的Bean,容器启动的时候不创建对象,第一次获取Bean的时候创建并初始化对象。

@Configuration
public class AppConfig2 {
    @Lazy
    @Bean
    public Person person() {
        System.out.println("给spring ioc容器中添加bean");
        return new Person("Mate", 12);
    }
}

单元测试:

public void test02() {

        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);
        System.out.println("spring ioc容器启动完成");
        ctx.getBean("person");
    }

运行结果:
spring ioc容器启动完成
给spring ioc容器中添加bean

@Conditional

按照一定条件进行判断,满足条件就给容器注册Bean。

  • 可以注解在Bean方法,表示满足当前条件,这个Bean的注册才生效。
  • 可以注解在配置类上,表示满足当前条件,这个配置类中的所有Bean注册才能生效。

假如现在要根据当前操作系统类型注入一个Person对象,如果是Mac OS就注入乔布斯,如果是Windows系统就注入比尔盖茨。

/*配置类*/
@Configuration
public class AppConfig2 {
    /*配置一个乔布斯*/
    @Bean("Steve Jobs")
    public Person appleFounder() {
        return new Person("Steve Jobs", 40);
    }
    /*配置一个比尔盖茨*/
    @Bean("Bill Gates")
    public Person winFounder() {
        return new Person("Bill Gates", 37);
    }
}

自定义注入条件,实现Condition接口

/**
 * mac环境时注入条件
 */
public class MacCondition implements Condition {
    /**
     * @param context  判断条件能使用的上下文
     * @param metadata 注释信息
     * @return
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        /*获取容器使用的beanFactory*/
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();

        /*获取类加载器*/
        ClassLoader classLoader = context.getClassLoader();

        /*获取bean定义的注册类*/
        BeanDefinitionRegistry registry = context.getRegistry();

        /*获取当前的环境信息*/
        Environment environment = context.getEnvironment();

        if (environment.getProperty("os.name").contains("Mac")) {
            return true;
        }
        return false;
    }
}

/**
 * windows时注入条件
 */
public class WinCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        /*获取当前的环境信息*/
        Environment environment = context.getEnvironment();

        if (environment.getProperty("os.name").contains("Win")) {
            return true;
        }
        return false;
    }
}

单元测试:

public void test03() {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig2.class);
        /*获取所有的bean*/
        Map<String, Person> beansOfType = ctx.getBeansOfType(Person.class);
        System.out.println(beansOfType);
    }

运行结果中只注入了乔布斯,因为当前的开发环境时Mac OS:

{Steve Jobs=Person(name=Steve Jobs, age=40)}

一只小小鸟
144 声望25 粉丝

如何做一个深层次的思考者,从简单开始、从记录开始。